Reading libraries and parameters

library(tidyverse)
library(quickpsy)
library(cowplot)
list.files("R", full.names = TRUE) %>% walk(source)
source("graphical_parameters.R")
source("parameters.R")
load(file = "logdata/dat_sym.RData")

No two guess

fun_sym_no_two_guess <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[5] + + (1 - p[5] - p[6]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[7] + (1 - p[7] - p[8]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_no_two_guess <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_no_two_guess,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_no_two_guess$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_no_two_guess$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

Two guess

fun_sym_two_guess <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[5] + p[7] + (1 - 2 * p[5] - p[7]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[6] + (1 - 2 * p[6] - p[7]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_two_guess <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_two_guess,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_two_guess$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_two_guess$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess vs two guess

sym_no_two_guess_vs_two_guess <- model_selection_lrt(
  fit_sym_no_two_guess$logliks, 
  fit_sym_two_guess$logliks) 
sym_no_two_guess_vs_two_guess %>% 
  group_by(best) %>% 
  count()
best_sym_no_two_guess <- sym_no_two_guess_vs_two_guess %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
best_sym_two_guess <- sym_no_two_guess_vs_two_guess %>% 
  filter(best == "second") %>% 
  select(subject, vertical)

No two guess same slope

fun_sym_no_two_guess_same_slope <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[4] + + (1 - p[4] - p[5]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[6] + (1 - p[6] - p[7]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_no_two_guess_same_slope <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_no_two_guess_same_slope,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_no_two_guess_same_slope$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_no_two_guess_same_slope$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess vs no two guess same slope

sym_no_two_guess_vs_no_two_guess_same_slope <- model_selection_lrt(
  fit_sym_no_two_guess$logliks, 
  fit_sym_no_two_guess_same_slope$logliks) 
sym_no_two_guess_vs_no_two_guess_same_slope %>%
  semi_join(best_sym_no_two_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_no_two_guess_no_same_slope <- sym_no_two_guess_vs_no_two_guess_same_slope %>% 
  semi_join(best_sym_no_two_guess) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_two_guess_same_slope <- sym_no_two_guess_vs_no_two_guess_same_slope %>% 
  semi_join(best_sym_no_two_guess) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

Sym guess

fun_sym_guess <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[6] + (1 - 2 * p[6]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_guess <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_guess,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, pini_scale, 
                              pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_guess$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_guess$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Sym guess vs no sym guess

sym_two_guess_vs_sym_guess <- model_selection_lrt(
  fit_sym_two_guess$logliks, 
  fit_sym_guess$logliks) 
sym_two_guess_vs_sym_guess %>%
  semi_join(best_sym_two_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_guess <- best_sym_two_guess

Sym same guess

fun_sym_same_guess <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_same_guess <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess vs no same slope

sym_same_guess_vs_no_same_guess <- model_selection_lrt(
  fit_sym_guess$logliks, 
  fit_sym_same_guess$logliks) 
sym_same_guess_vs_no_same_guess %>%
  semi_join(best_sym_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_no_same_guess <- sym_same_guess_vs_no_same_guess %>% 
  semi_join(best_sym_guess) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
best_sym_same_guess <- sym_same_guess_vs_no_same_guess %>% 
  semi_join(best_sym_guess) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

No same guess same slope

fun_sym_guess_same_slope <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[5] + (1 - 2 * p[5]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_guess_same_slope <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_guess_same_slope,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, 
                              pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_guess_same_slope$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_guess_same_slope$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

No same guess vs no same guess same slope

sym_same_guess_vs_same_guess_same_slope <- model_selection_lrt(
  fit_sym_guess$logliks, 
  fit_sym_guess_same_slope$logliks) 
sym_same_guess_vs_same_guess_same_slope %>%
  semi_join(best_sym_no_same_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_same_guess_same_slope <- best_sym_no_same_guess
  

Absent lapses

fun_sym_absent_lapses <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] - p[2], p[4]))))
fit_sym_absent_lapses <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses vs no absent lapses

sym_absent_lapses_vs_no_absent_lapses <- model_selection_lrt(
  fit_sym_same_guess$logliks, 
  fit_sym_absent_lapses$logliks) 
sym_absent_lapses_vs_no_absent_lapses %>%
  semi_join(best_sym_same_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_no_absent_lapses <- sym_absent_lapses_vs_no_absent_lapses %>% 
  semi_join(best_sym_same_guess) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
best_sym_absent_lapses <- sym_absent_lapses_vs_no_absent_lapses %>% 
  semi_join(best_sym_same_guess) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

Sym same guess same slope

fun_sym_same_guess_same_slope <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_same_guess_same_slope <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_same_slope,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_same_slope$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_same_slope$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

No absent lapses vs no absent lapses same slope

sym_no_absent_lapses_vs_no_absent_lapses_same_slope <- model_selection_lrt(
  fit_sym_same_guess$logliks, 
  fit_sym_same_guess_same_slope$logliks) 
sym_no_absent_lapses_vs_no_absent_lapses_same_slope %>%
  semi_join(best_sym_no_absent_lapses) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_absent_lapses_no_same_slope <- sym_no_absent_lapses_vs_no_absent_lapses_same_slope %>% 
  semi_join(best_sym_no_absent_lapses) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_absent_lapses_same_slope <- sym_no_absent_lapses_vs_no_absent_lapses_same_slope %>% 
  semi_join(best_sym_no_absent_lapses) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

Absent lapses same slope

fun_sym_absent_lapses_same_slope <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] + p[2], p[3]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1] - p[2], p[3]))))
fit_sym_absent_lapses_same_slope <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_same_slope,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_origin, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_same_slope$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_same_slope$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses vs absent lapses same slope

sym_absent_lapses_vs_absent_lapses_same_slope <- model_selection_lrt(
  fit_sym_absent_lapses$logliks, 
  fit_sym_absent_lapses_same_slope$logliks) 
sym_absent_lapses_vs_absent_lapses_same_slope %>%
  semi_join(best_sym_absent_lapses) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_absent_lapses_no_same_slope <- sym_absent_lapses_vs_absent_lapses_same_slope %>% 
  semi_join(best_sym_absent_lapses) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_absent_lapses_same_slope <- sym_absent_lapses_vs_absent_lapses_same_slope %>% 
  semi_join(best_sym_absent_lapses) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

Averages, curves and parameters (checking)

sym_averages_s_vs_d_test <- 
  (fit_sym_no_two_guess_same_slope$averages %>% semi_join(best_sym_no_two_guess_same_slope))
Joining, by = c("subject", "vertical")
sym_curves_s_vs_d_test <- 
  (fit_sym_no_two_guess_same_slope$curves %>% semi_join(best_sym_no_two_guess_same_slope))
Joining, by = c("subject", "vertical")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = sym_averages_s_vs_d_test, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = sym_curves_s_vs_d_test, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

sym_averages_s_vs_d_test <- 
  (fit_sym_same_guess_same_slope$averages %>% semi_join(best_sym_no_absent_lapses_same_slope))
Joining, by = c("subject", "vertical")
sym_curves_s_vs_d_test <- 
  (fit_sym_same_guess_same_slope$curves %>% semi_join(best_sym_no_absent_lapses_same_slope))
Joining, by = c("subject", "vertical")
ggplot() + facet_wrap(subject ~ vertical) +
  geom_point(data = sym_averages_s_vs_d_test, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = sym_curves_s_vs_d_test, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

sym_averages_s_vs_d_test <- 
  (fit_sym_absent_lapses$averages %>% semi_join(best_sym_absent_lapses_no_same_slope))
Joining, by = c("subject", "vertical")
sym_curves_s_vs_d_test <- 
  (fit_sym_absent_lapses$curves %>% semi_join(best_sym_absent_lapses_no_same_slope))
Joining, by = c("subject", "vertical")
ggplot() + facet_wrap(subject ~ vertical) +
  geom_point(data = sym_averages_s_vs_d_test, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = sym_curves_s_vs_d_test, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

Indecision model

Averages, curves and parameters

Plotting thresholds

ggplot() + facet_wrap(subject ~ vertical) +
  geom_point(data = sym_averages_s_vs_d, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = sym_curves_s_vs_d, 
            aes(x = x, y = y, color = references)) +
  geom_segment(data = sym_thre_s_vs_d, 
           aes(x = thre, xend = thre, y = 0 , yend = prob, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess same slope zero

fun_sym_no_two_guess_same_slope_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[2] + + (1 - p[2] - p[3]) * pnorm(x, 0, p[1]), 
    function(x, p) p[4] + (1 - p[4] - p[5]) * pnorm(x, 0, p[1]))))
fit_sym_no_two_guess_same_slope_zero <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_no_two_guess_same_slope_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_no_two_guess_same_slope_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_no_two_guess_same_slope_zero$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess same slope zero vs no two guess same slope

sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero <- model_selection_lrt(
  fit_sym_no_two_guess_same_slope$logliks, 
  fit_sym_no_two_guess_same_slope_zero$logliks) 
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero %>%
  semi_join(best_sym_no_two_guess_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_no_two_guess_same_slope_no_zero <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero %>% 
  semi_join(best_sym_no_two_guess_same_slope) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_two_guess_same_slope_zero <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_zero %>% 
  semi_join(best_sym_no_two_guess_same_slope) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "zero")
Joining, by = c("subject", "vertical")

No two guess same slope s

fun_sym_no_two_guess_same_slope_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + + (1 - p[3] - p[4]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[5] + (1 - p[5] - p[6]) * pnorm(x, p[1], p[2]))))
fit_sym_no_two_guess_same_slope_s <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_no_two_guess_same_slope_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_no_two_guess_same_slope_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_no_two_guess_same_slope_s$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess same slope vs no two guess same slope s

sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_s <- model_selection_lrt(
  fit_sym_no_two_guess_same_slope$logliks, 
  fit_sym_no_two_guess_same_slope_s$logliks) 
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_s %>%
  semi_join(best_sym_no_two_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")

No two guess same slope d

fun_sym_no_two_guess_same_slope_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + + (1 - p[3] - p[4]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[5] + (1 - p[5] - p[6]) * pnorm(x, -p[1], p[2]))))
fit_sym_no_two_guess_same_slope_d <- quickpsy(dat_sym, orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_no_two_guess_same_slope_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse, pini_lapse, pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_no_two_guess_same_slope_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_no_two_guess_same_slope_d$curves, 
            aes(x = x, y = y, color = references)) +
  theme_grey() + theme(legend.position = "top") 

No two guess same slope vs no two guess same slope d

sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d <- model_selection_lrt(
  fit_sym_no_two_guess_same_slope$logliks, 
  fit_sym_no_two_guess_same_slope_d$logliks) 
sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d %>%
  semi_join(best_sym_no_two_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_no_two_guess_same_slope_no_zero_s <- sym_no_two_guess_same_slope_vs_no_two_guess_same_slope_d %>% 
  semi_join(best_sym_no_two_guess_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")

No same guess same slope zero

fun_sym_guess_same_slope_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]), 
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[1]))))
fit_sym_guess_same_slope_zero <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_guess_same_slope_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale, 
                              pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_guess_same_slope_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_guess_same_slope_zero$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

No same guess same slope vs no same guess same slope zero

sym_guess_same_slope_vs_sym_guess_same_slope_zero <- model_selection_lrt(
  fit_sym_guess_same_slope$logliks, 
  fit_sym_guess_same_slope_zero$logliks) 
sym_guess_same_slope_vs_sym_guess_same_slope_zero %>%
  semi_join(best_sym_no_same_guess) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_guess_same_slope_no_zero <- sym_guess_same_slope_vs_sym_guess_same_slope_zero %>% 
  semi_join(best_sym_no_same_guess) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_guess_same_slope_zero <- sym_guess_same_slope_vs_sym_guess_same_slope_zero %>% 
  semi_join(best_sym_no_same_guess) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "zero")
Joining, by = c("subject", "vertical")

No same guess same slope s

fun_sym_guess_same_slope_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]))))
fit_sym_guess_same_slope_s <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_guess_same_slope_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_guess_same_slope_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_guess_same_slope_s$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

No same guess same slope no zero vs no same guess same slope no zero s

sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s <- model_selection_lrt(
  fit_sym_guess_same_slope$logliks, 
  fit_sym_guess_same_slope_s$logliks) 
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s %>%
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_guess_same_slope_no_zero_no_s <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s %>% 
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
best_sym_guess_same_slope_no_zero_s <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_s %>% 
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")

No same guess same slope d

fun_sym_guess_same_slope_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, -p[1], p[2]))))
fit_sym_guess_same_slope_d <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_guess_same_slope_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse, pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_guess_same_slope_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_guess_same_slope_d$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

No same guess same slope no zero vs no same guess same slope no zero d

sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d <- model_selection_lrt(
  fit_sym_guess_same_slope$logliks, 
  fit_sym_guess_same_slope_d$logliks) 
sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d %>%
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_guess_same_slope_no_zero_no_d <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d %>% 
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_guess_same_slope_no_zero_d <- sym_guess_same_slope_no_zero_vs_guess_same_slope_no_zero_d %>% 
  semi_join(best_sym_guess_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "decision")
Joining, by = c("subject", "vertical")

Sym same guess no same slope

fun_sym_same_guess_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[1]), 
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, 0, p[2]))))
fit_sym_same_guess_zero <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_zero$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess no same slope no zero vs Same guess no same slope zero

sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero <- model_selection_lrt(
  fit_sym_same_guess$logliks, 
  fit_sym_same_guess_zero$logliks) 
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_zero %>%
  semi_join(best_sym_no_absent_lapses_no_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")

Sym same guess no same slope no zero s

fun_sym_same_guess_no_zero_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[3]))))
fit_sym_same_guess_no_zero_s <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_no_zero_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_no_zero_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_no_zero_s$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess no same slope no zero vs Same guess no same slope no zero s

sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s <- model_selection_lrt(
  fit_sym_same_guess$logliks, 
  fit_sym_same_guess_no_zero_s$logliks) 
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s %>%
  semi_join(best_sym_no_absent_lapses_no_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")

Sym same guess no same slope no zero d

fun_sym_same_guess_no_zero_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[4] + (1 - 2 * p[4]) * pnorm(x, -p[1], p[3]))))
fit_sym_same_guess_no_zero_d <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_no_zero_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_no_zero_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_no_zero_d$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess no same slope no zero vs Same guess no same slope no zero d

sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_d <- model_selection_lrt(
  fit_sym_same_guess$logliks, 
  fit_sym_same_guess_no_zero_d$logliks) 
sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_d %>%
  semi_join(best_sym_no_absent_lapses_no_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_same_guess_no_same_slope_no_zero_full <- sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s %>% 
  semi_join(best_sym_no_absent_lapses_no_same_slope) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) %>% 
  mutate(best = "full")
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_same_guess_no_same_slope_no_zero_s <- sym_same_guess_no_same_slope_no_zero_vs_same_guess_no_same_slope_no_zero_s %>% 
  semi_join(best_sym_no_absent_lapses_no_same_slope) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")

Sym same guess same slope zero

fun_sym_same_guess_same_slope_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]), 
    function(x, p) p[2] + (1 - 2 * p[2]) * pnorm(x, 0, p[1]))))
fit_sym_same_guess_same_slope_zero <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_same_slope_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_same_slope_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_same_slope_zero$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess same slope no zero vs same guess same slope zero

sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero <- model_selection_lrt(
  fit_sym_same_guess_same_slope$logliks, 
  fit_sym_same_guess_same_slope_zero$logliks) 
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero %>%
  semi_join(best_sym_no_absent_lapses_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_sym_same_guess_same_slope_no_zero <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero %>% 
  semi_join(best_sym_no_absent_lapses_same_slope) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) 
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_same_guess_same_slope_zero <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_zero %>% 
  semi_join(best_sym_no_absent_lapses_same_slope) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "zero")
Joining, by = c("subject", "vertical")

Sym same guess same slope no zero s

fun_sym_same_guess_same_slope_no_zero_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]))))
fit_sym_same_guess_same_slope_no_zero_s <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_same_slope_no_zero_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_same_slope_no_zero_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_same_slope_no_zero_s$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess same slope no zero vs same guess same slope no zero s

sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s <- model_selection_lrt(
  fit_sym_same_guess_same_slope$logliks, 
  fit_sym_same_guess_same_slope_no_zero_s$logliks) 
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s %>%
  semi_join(best_sym_same_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")

Sym same guess same slope no zero d

fun_sym_same_guess_same_slope_no_zero_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, p[1], p[2]), 
    function(x, p) p[3] + (1 - 2 * p[3]) * pnorm(x, -p[1], p[2]))))
fit_sym_same_guess_same_slope_no_zero_d <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_same_guess_same_slope_no_zero_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, 
                              pini_lapse),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_same_guess_same_slope_no_zero_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_same_guess_same_slope_no_zero_d$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Same guess same slope no zero vs same guess same slope no zero d

sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_d <- model_selection_lrt(
  fit_sym_same_guess_same_slope$logliks, 
  fit_sym_same_guess_same_slope_no_zero_d$logliks) 
sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_d %>%
  semi_join(best_sym_same_guess_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_same_guess_same_slope_no_zero_full <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s %>% 
  semi_join(best_sym_same_guess_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) %>% 
  mutate(best = "full")
Joining, by = c("subject", "vertical")
### Add to s vs d
best_sym_same_guess_same_slope_no_zero_s <- sym_same_guess_same_slope_no_zero_vs_same_guess_same_slope_no_zero_s %>% 
  semi_join(best_sym_same_guess_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")

Absent lapses no same slope zero

fun_sym_absent_lapses_no_same_slope_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[2]))))
fit_sym_absent_lapses_no_same_slope_zero <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_no_same_slope_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_no_same_slope_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_no_same_slope_zero$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses no same slope vs absent lapses no same slope zero

rr sym_absent_lapses_no_same_slope_vs_absent_lapses_no_same_slope_zero <- model_selection_lrt( fit_sym_absent_lapses\(logliks, fit_sym_absent_lapses_no_same_slope_zero\)logliks) sym_absent_lapses_no_same_slope_vs_absent_lapses_no_same_slope_zero %>% semi_join(best_sym_absent_lapses_no_same_slope) %>% group_by(best) %>% count()

Joining, by = c(\subject\, \vertical\)

Absent lapses no same slope no zero s

fun_sym_absent_lapses_no_same_slope_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[3]))))
fit_sym_absent_lapses_no_same_slope_s <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_no_same_slope_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_no_same_slope_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_no_same_slope_s$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses no same slope no zero vs absent lapses no same slope no zero s

sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s <- model_selection_lrt(
  fit_sym_absent_lapses$logliks, 
  fit_sym_absent_lapses_no_same_slope_s$logliks) 
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_s %>%
  semi_join(best_sym_absent_lapses_no_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")

Absent lapses no same slope no zero s

fun_sym_absent_lapses_no_same_slope_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, -p[1], p[3]))))
fit_sym_absent_lapses_no_same_slope_d <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_no_same_slope_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_no_same_slope_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_no_same_slope_d$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses no same slope no zero vs absent lapses no same slope no zero d

sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d <- model_selection_lrt(
  fit_sym_absent_lapses$logliks, 
  fit_sym_absent_lapses_no_same_slope_d$logliks) 
sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d %>%
  semi_join(best_sym_absent_lapses_no_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_absent_lapses_no_same_slope_no_zero_s <- sym_absent_lapses_no_same_slope_no_zero_vs_absent_lapses_no_same_slope_no_zero_d %>% 
  semi_join(best_sym_absent_lapses_no_same_slope) %>% 
  filter(best == "first") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")

Absent lapses same slope zero

fun_sym_absent_lapses_same_slope_zero <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, 0, p[1]))))
fit_sym_absent_lapses_same_slope_zero <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_same_slope_zero,
                xmin = -3, xmax = 3,
                parini = list(pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_same_slope_zero$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_same_slope_zero$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses same slope no zero vs absent lapses same slope zero

sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero <- model_selection_lrt(
  fit_sym_absent_lapses_same_slope$logliks, 
  fit_sym_absent_lapses_same_slope_zero$logliks) 
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero %>%
  semi_join(best_sym_absent_lapses_same_slope) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_absent_lapses_same_slope_no_zero <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero %>% 
  semi_join(best_sym_absent_lapses_same_slope) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
### Add to s vs d
best_absent_lapses_same_slope_zero <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_zero %>% 
  semi_join(best_sym_absent_lapses_same_slope) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "zero")
Joining, by = c("subject", "vertical")

Absent lapses same slope no zero s

fun_sym_absent_lapses_same_slope_no_zero_s <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]))))
fit_sym_absent_lapses_same_slope_no_zero_s <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_same_slope_no_zero_s,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_same_slope_no_zero_s$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_same_slope_no_zero_s$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses same slope no zero vs absent lapses same slope no zero s

sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s <- model_selection_lrt(
  fit_sym_absent_lapses_same_slope$logliks, 
  fit_sym_absent_lapses_same_slope_no_zero_s$logliks) 
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s %>%
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
best_absent_lapses_same_slope_no_zero_no_s <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s %>% 
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  select(subject, vertical)
Joining, by = c("subject", "vertical")
best_absent_lapses_same_slope_no_zero_s <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s %>% 
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) 
Joining, by = c("subject", "vertical")

Absent lapses same slope no zero d

fun_sym_absent_lapses_same_slope_no_zero_d <-  dat_sym %>% 
  distinct(references) %>% 
  bind_cols(tibble(fun = c(
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, p[1], p[2]), 
    function(x, p) 0.01 + (1 - 2 * 0.01) * pnorm(x, -p[1], p[2]))))
fit_sym_absent_lapses_same_slope_no_zero_d <- quickpsy(dat_sym, 
                               orientation, response, 
                grouping = .(subject, vertical, references),
                fun = fun_sym_absent_lapses_same_slope_no_zero_d,
                xmin = -3, xmax = 3,
                parini = list(pini_origin, pini_scale),
                bootstrap = "none")
ggplot() + facet_wrap(subject ~ vertical, ncol = 6) +
  geom_point(data = fit_sym_absent_lapses_same_slope_no_zero_d$averages, 
             aes(x = orientation, y = prob, color = references)) +
  geom_line(data = fit_sym_absent_lapses_same_slope_no_zero_d$curves, 
            aes(x = x, y = y, color = references, lty = "all")) +
  theme_grey() + theme(legend.position = "top") 

Absent lapses same slope no zero vs absent lapses same slope no zero d

sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_d <- model_selection_lrt(
  fit_sym_absent_lapses_same_slope$logliks, 
  fit_sym_absent_lapses_same_slope_no_zero_d$logliks) 
sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_d %>%
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  group_by(best) %>% 
  count()
Joining, by = c("subject", "vertical")
### Add to s vs d
best_absent_lapses_same_slope_no_zero_d <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_d %>% 
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "decision")
Joining, by = c("subject", "vertical")
### Add to s vs d
best_absent_lapses_same_slope_no_zero_no_d_s <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s %>% 
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  filter(best == "second") %>% 
  select(subject, vertical) %>% 
  mutate(best = "sensory")
Joining, by = c("subject", "vertical")
### Add to s vs d
best_absent_lapses_same_slope_no_zero_no_s <- sym_absent_lapses_same_slope_no_zero_vs_absent_lapses_same_slope_no_zero_s %>% 
  semi_join(best_absent_lapses_same_slope_no_zero) %>% 
  filter(best == "first") %>% 
  filter(!(subject == 9 & vertical == FALSE)) %>% 
  select(subject, vertical) %>% 
  mutate(best = "full")
Joining, by = c("subject", "vertical")

Add all best

Save data

save(sym_averages_s_vs_d_best, file = "logdata/sym_averages_s_vs_d_best.RData")
save(sym_curves_s_vs_d_best, file = "logdata/sym_curves_s_vs_d_best.RData")
save(sym_par_s_vs_d_best, file = "logdata/sym_par_s_vs_d_best.RData")
save(sym_par_s_vs_d_best_long, file = "logdata/sym_par_s_vs_d_best_long.RData")
save(sym_par_s_vs_d_best_abs, file = "logdata/sym_par_s_vs_d_best_abs.RData")
LS0tCnRpdGxlOiAiU3ltbWV0cmljIHRhc2sgIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgUmVhZGluZyBsaWJyYXJpZXMgYW5kIHBhcmFtZXRlcnMKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShxdWlja3BzeSkKbGlicmFyeShjb3dwbG90KQoKbGlzdC5maWxlcygiUiIsIGZ1bGwubmFtZXMgPSBUUlVFKSAlPiUgd2Fsayhzb3VyY2UpCnNvdXJjZSgiZ3JhcGhpY2FsX3BhcmFtZXRlcnMuUiIpCnNvdXJjZSgicGFyYW1ldGVycy5SIikKCmxvYWQoZmlsZSA9ICJsb2dkYXRhL2RhdF9zeW0uUkRhdGEiKQpgYGAKCiMjIyBObyB0d28gZ3Vlc3MgIApgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fbm9fdHdvX2d1ZXNzIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICsgKDEgLSBwWzVdIC0gcFs2XSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs3XSArICgxIC0gcFs3XSAtIHBbOF0pICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbNF0pKSkpCgpmaXRfc3ltX25vX3R3b19ndWVzcyA8LSBxdWlja3BzeShkYXRfc3ltLCBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fbm9fdHdvX2d1ZXNzLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fbm9fdHdvX2d1ZXNzJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBUd28gZ3Vlc3MKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3R3b19ndWVzcyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNV0gKyBwWzddICsgKDEgLSAyICogcFs1XSAtIHBbN10pICogcG5vcm0oeCwgcFsxXSArIHBbMl0sIHBbM10pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNl0gKyAoMSAtIDIgKiBwWzZdIC0gcFs3XSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFs0XSkpKSkKCmZpdF9zeW1fdHdvX2d1ZXNzIDwtIHF1aWNrcHN5KGRhdF9zeW0sIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV90d29fZ3Vlc3MsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV90d29fZ3Vlc3MkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fdHdvX2d1ZXNzJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHR3byBndWVzcyB2cyB0d28gZ3Vlc3MKYGBge3J9CnN5bV9ub190d29fZ3Vlc3NfdnNfdHdvX2d1ZXNzIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ub190d29fZ3Vlc3MkbG9nbGlrcywgCiAgZml0X3N5bV90d29fZ3Vlc3MkbG9nbGlrcykgCgpzeW1fbm9fdHdvX2d1ZXNzX3ZzX3R3b19ndWVzcyAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmJlc3Rfc3ltX25vX3R3b19ndWVzcyA8LSBzeW1fbm9fdHdvX2d1ZXNzX3ZzX3R3b19ndWVzcyAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmJlc3Rfc3ltX3R3b19ndWVzcyA8LSBzeW1fbm9fdHdvX2d1ZXNzX3ZzX3R3b19ndWVzcyAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpCgpgYGAKCiMjIyBObyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZSAgCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyArICgxIC0gcFs0XSAtIHBbNV0pICogcG5vcm0oeCwgcFsxXSArIHBbMl0sIHBbM10pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNl0gKyAoMSAtIHBbNl0gLSBwWzddKSAqIHBub3JtKHgsIHBbMV0gLSBwWzJdLCBwWzNdKSkpKQoKZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSA8LSBxdWlja3BzeShkYXRfc3ltLCBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBObyB0d28gZ3Vlc3MgdnMgbm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUKYGBge3J9CnN5bV9ub190d29fZ3Vlc3NfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX25vX3R3b19ndWVzcyRsb2dsaWtzLCAKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlJGxvZ2xpa3MpIAoKc3ltX25vX3R3b19ndWVzc192c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmJlc3Rfc3ltX25vX3R3b19ndWVzc19ub19zYW1lX3Nsb3BlIDwtIHN5bV9ub190d29fZ3Vlc3NfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3MpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUgPC0gc3ltX25vX3R3b19ndWVzc192c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzcykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKQoKYGBgCgojIyMgU3ltIGd1ZXNzCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzcyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNV0gKyAoMSAtIDIgKiBwWzVdKSAqIHBub3JtKHgsIHBbMV0gKyBwWzJdLCBwWzNdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzZdICsgKDEgLSAyICogcFs2XSkgKiBwbm9ybSh4LCBwWzFdIC0gcFsyXSwgcFs0XSkpKSkKCmZpdF9zeW1fZ3Vlc3MgPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fZ3Vlc3MsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ndWVzcyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ndWVzcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgoKIyMjIFN5bSBndWVzcyB2cyBubyBzeW0gZ3Vlc3MKYGBge3J9CnN5bV90d29fZ3Vlc3NfdnNfc3ltX2d1ZXNzIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV90d29fZ3Vlc3MkbG9nbGlrcywgCiAgZml0X3N5bV9ndWVzcyRsb2dsaWtzKSAKCnN5bV90d29fZ3Vlc3NfdnNfc3ltX2d1ZXNzICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV90d29fZ3Vlc3MpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fZ3Vlc3MgPC0gYmVzdF9zeW1fdHdvX2d1ZXNzCmBgYAoKCgojIyMgU3ltIHNhbWUgZ3Vlc3MKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3MgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzVdICsgKDEgLSAyICogcFs1XSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICgxIC0gMiAqIHBbNV0pICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbNF0pKSkpCgpmaXRfc3ltX3NhbWVfZ3Vlc3MgPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fc2FtZV9ndWVzcywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3MkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgU2FtZSBndWVzcyB2cyBubyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fc2FtZV9ndWVzc192c19ub19zYW1lX2d1ZXNzIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ndWVzcyRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3MkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc192c19ub19zYW1lX2d1ZXNzICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzcykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub19zYW1lX2d1ZXNzIDwtIHN5bV9zYW1lX2d1ZXNzX3ZzX25vX3NhbWVfZ3Vlc3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzcykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpCgpiZXN0X3N5bV9zYW1lX2d1ZXNzIDwtIHN5bV9zYW1lX2d1ZXNzX3ZzX25vX3NhbWVfZ3Vlc3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzcykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKQoKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gMiAqIHBbNF0pICogcG5vcm0oeCwgcFsxXSArIHBbMl0sIHBbM10pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNV0gKyAoMSAtIDIgKiBwWzVdKSAqIHBub3JtKHgsIHBbMV0gLSBwWzJdLCBwWzNdKSkpKQoKZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlIDwtIHF1aWNrcHN5KGRhdF9zeW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2d1ZXNzX3NhbWVfc2xvcGUsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKCiMjIyBObyBzYW1lIGd1ZXNzIHZzIG5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZQpgYGB7cn0Kc3ltX3NhbWVfZ3Vlc3NfdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ndWVzcyRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc192c19zYW1lX2d1ZXNzX3NhbWVfc2xvcGUgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fbm9fc2FtZV9ndWVzc19zYW1lX3Nsb3BlIDwtIGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MKICAKCmBgYAoKIyMjIEFic2VudCBsYXBzZXMKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXMgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbNF0pKSkpCgpmaXRfc3ltX2Fic2VudF9sYXBzZXMgPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlcywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgcGluaV9zY2FsZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlcyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHZzIG5vIGFic2VudCBsYXBzZXMKYGBge3J9CnN5bV9hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXMgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3NhbWVfZ3Vlc3MkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzJGxvZ2xpa3MpIAoKc3ltX2Fic2VudF9sYXBzZXNfdnNfbm9fYWJzZW50X2xhcHNlcyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fc2FtZV9ndWVzcykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX25vX2Fic2VudF9sYXBzZXMgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmJlc3Rfc3ltX2Fic2VudF9sYXBzZXMgPC0gc3ltX2Fic2VudF9sYXBzZXNfdnNfbm9fYWJzZW50X2xhcHNlcyAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3MpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIHNhbWUgc2xvcGUgCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzRdICsgKDEgLSAyICogcFs0XSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gMiAqIHBbNF0pICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbM10pKSkpCgpmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBObyBhYnNlbnQgbGFwc2VzIHZzIG5vIGFic2VudCBsYXBzZXMgc2FtZSBzbG9wZQpgYGB7cn0Kc3ltX25vX2Fic2VudF9sYXBzZXNfdnNfbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlJGxvZ2xpa3MpIAoKc3ltX25vX2Fic2VudF9sYXBzZXNfdnNfbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSA8LSBzeW1fbm9fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSA8LSBzeW1fbm9fYWJzZW50X2xhcHNlc192c19ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpCgpgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdICsgcFsyXSwgcFszXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSAtIHBbMl0sIHBbM10pKSkpCgpmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9vcmlnaW4sIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgdnMgYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2Fic2VudF9sYXBzZXMkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXMpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXMpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXMpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmBgYAoKCiMjIyBBdmVyYWdlcywgY3VydmVzIGFuZCBwYXJhbWV0ZXJzIChjaGVja2luZykKYGBge3J9CnN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdCA8LSAKICAoZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUpKQoKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0LCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBzeW1fY3VydmVzX3NfdnNfZF90ZXN0LCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgpgYGB7cn0Kc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0IDwtIAogIChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19zYW1lX2d1ZXNzKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZSRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19zYW1lX2d1ZXNzKSkKCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0LCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBzeW1fY3VydmVzX3NfdnNfZF90ZXN0LCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgpgYGB7cn0Kc3ltX2F2ZXJhZ2VzX3NfdnNfZF90ZXN0IDwtIAogIChmaXRfc3ltX3NhbWVfZ3Vlc3MkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpKQoKc3ltX2N1cnZlc19zX3ZzX2RfdGVzdCA8LSAKICAoZml0X3N5bV9zYW1lX2d1ZXNzJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpCgpzeW1fY3VydmVzX3NfdnNfZF90ZXN0X2dwIDwtIAogIChmaXRfc3ltX3NhbWVfZ3Vlc3NfZ3AkY3VydmVzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSkKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwpICsKICBnZW9tX3BvaW50KGRhdGEgPSBzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCmBgYHtyfQpzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkpCgoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdCwgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gc3ltX2N1cnZlc19zX3ZzX2RfdGVzdCwgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKYGBge3J9CnN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdCA8LSAKICAoZml0X3N5bV9hYnNlbnRfbGFwc2VzJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fYWJzZW50X2xhcHNlcyRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpKQoKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwpICsKICBnZW9tX3BvaW50KGRhdGEgPSBzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IHN5bV9jdXJ2ZXNfc192c19kX3Rlc3QsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD04fQpzeW1fYXZlcmFnZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSkKCnN5bV9jdXJ2ZXNfc192c19kX3Rlc3QgPC0gCiAgKGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN5bV9hdmVyYWdlc19zX3ZzX2RfdGVzdCwgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gc3ltX2N1cnZlc19zX3ZzX2RfdGVzdCwKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMjIEluZGVjaXNpb24gbW9kZWwgCmBgYHtyfQoKYGBgCgojIyMgQXZlcmFnZXMsIGN1cnZlcyBhbmQgcGFyYW1ldGVycyAKYGBge3IgZmlnLmhlaWdodD0xNSwgZmlnLndpZHRoPTE1fQpzeW1fYXZlcmFnZXNfc192c19kIDwtIAogIChmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlJGF2ZXJhZ2VzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19zYW1lX2d1ZXNzKSkpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fc2FtZV9ndWVzcyRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSRhdmVyYWdlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXMkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUkYXZlcmFnZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkKCnN5bV9jdXJ2ZXNfc192c19kIDwtIAogIChmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9hYnNlbnRfbGFwc2VzJGN1cnZlcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSRjdXJ2ZXMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkKCnN5bV9wYXJfc192c19kIDwtIAogIChmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSRwYXIgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9hYnNlbnRfbGFwc2VzJHBhciAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSRwYXIgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkKCnN5bV90aHJlX3NfdnNfZCA8LSAKICAoZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSR0aHJlc2hvbGRzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGUkdGhyZXNob2xkcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzJHRocmVzaG9sZHMgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUkdGhyZXNob2xkcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXMkdGhyZXNob2xkcyAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSR0aHJlc2hvbGRzICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSkpCgpzeW1fZGV2X3NfdnNfZCA8LSAKICAoZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSRkZXZpYW5jZSAlPiUgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlJGRldmlhbmNlICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fc2FtZV9ndWVzcykpKSAlPiUgCiAgYmluZF9yb3dzKChmaXRfc3ltX3NhbWVfZ3Vlc3MkZGV2aWFuY2UgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUkZGV2aWFuY2UgJT4lIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpKSkgJT4lIAogIGJpbmRfcm93cygoZml0X3N5bV9hYnNlbnRfbGFwc2VzJGRldmlhbmNlICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSkpICU+JSAKICBiaW5kX3Jvd3MoKGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlJGRldmlhbmNlICU+JSBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSkpCgoKc3ltX2Rldl9zX3ZzX2QgJT4lIAogIGZpbHRlcihwX3ZhbHVlX2NoaV9zcXIgPCBhbHBoYSkKCnN5bV9wYXJfc192c19kX2xvbmcgPC0gc3ltX3Bhcl9zX3ZzX2QgJT4lIAogIHNwcmVhZChwYXJuLHBhcikgCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3ltX2F2ZXJhZ2VzX3NfdnNfZCwgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gc3ltX2N1cnZlc19zX3ZzX2QsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV92bGluZShkYXRhID0gc3ltX3Bhcl9zX3ZzX2RfbG9uZywgCiAgICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBwMSwgbHR5ID0gInAxIikpICsKICAgIGdlb21fdmxpbmUoZGF0YSA9IHN5bV9wYXJfc192c19kX2xvbmcsIAogICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gcDEgKyBwMiwgbHR5ID0gInAxICtwMiIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBQbG90dGluZyB0aHJlc2hvbGRzCgpgYGB7ciBmaWcuaGVpZ2h0PTE1LCBmaWcud2lkdGg9MTV9CmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwpICsKICBnZW9tX3BvaW50KGRhdGEgPSBzeW1fYXZlcmFnZXNfc192c19kLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBzeW1fY3VydmVzX3NfdnNfZCwgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX3NlZ21lbnQoZGF0YSA9IHN5bV90aHJlX3NfdnNfZCwgCiAgICAgICAgICAgYWVzKHggPSB0aHJlLCB4ZW5kID0gdGhyZSwgeSA9IDAgLCB5ZW5kID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgemVybwpgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbMl0gKyArICgxIC0gcFsyXSAtIHBbM10pICogcG5vcm0oeCwgMCwgcFsxXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gcFs0XSAtIHBbNV0pICogcG5vcm0oeCwgMCwgcFsxXSkpKSkKCmZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSBxdWlja3BzeShkYXRfc3ltLCBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlLCBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8kY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gdHdvIGd1ZXNzIHNhbWUgc2xvcGUgemVybyB2cyBubyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZQpgYGB7cn0Kc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8gPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlJGxvZ2xpa3MsIAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybyRsb2dsaWtzKSAKCnN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSkgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvIDwtIHN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSBzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfemVybyAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJ6ZXJvIikKCmBgYAoKIyMjIE5vIHR3byBndWVzcyBzYW1lIHNsb3BlIHMgIApgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfcyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbM10gKyArICgxIC0gcFszXSAtIHBbNF0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICgxIC0gcFs1XSAtIHBbNl0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfcyA8LSBxdWlja3BzeShkYXRfc3ltLCBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfcywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfcyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9zJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHR3byBndWVzcyBzYW1lIHNsb3BlIHZzIG5vIHR3byBndWVzcyBzYW1lIHNsb3BlIHMKYGBge3J9CnN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9zIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3MkbG9nbGlrcykgCgpzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfcyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCmBgYAoKIyMjIE5vIHR3byBndWVzcyBzYW1lIHNsb3BlIGQgIApgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZCA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbM10gKyArICgxIC0gcFszXSAtIHBbNF0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs1XSArICgxIC0gcFs1XSAtIHBbNl0pICogcG5vcm0oeCwgLXBbMV0sIHBbMl0pKSkpCgpmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QgPC0gcXVpY2twc3koZGF0X3N5bSwgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZCRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBObyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZSB2cyBubyB0d28gZ3Vlc3Mgc2FtZSBzbG9wZSBkCmBgYHtyfQpzeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfdnNfbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfZCA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGUkbG9nbGlrcywgCiAgZml0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kJGxvZ2xpa3MpIAoKc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3ZzX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX2QgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8pICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zIDwtIHN5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV92c19ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9kICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fdHdvX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzJdICsgKDEgLSAyICogcFsyXSkgKiBwbm9ybSh4LCAwLCBwWzFdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCAwLCBwWzFdKSkpKQoKZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UsIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8kY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB2cyBubyBzYW1lIGd1ZXNzIHNhbWUgc2xvcGUgemVybwpgYGB7cn0Kc3ltX2d1ZXNzX3NhbWVfc2xvcGVfdnNfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybyRsb2dsaWtzKSAKCnN5bV9ndWVzc19zYW1lX3Nsb3BlX3ZzX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvIDwtIHN5bV9ndWVzc19zYW1lX3Nsb3BlX3ZzX3N5bV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19zYW1lX2d1ZXNzKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSBzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV92c19zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fc2FtZV9ndWVzcykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiemVybyIpCgpgYGAKCiMjIyBObyBzYW1lIGd1ZXNzIHNhbWUgc2xvcGUgcwpgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9zIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFszXSArICgxIC0gMiAqIHBbM10pICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFs0XSArICgxIC0gMiAqIHBbNF0pICogcG5vcm0oeCwgcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9zIDwtIHF1aWNrcHN5KGRhdF9zeW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2d1ZXNzX3NhbWVfc2xvcGVfcywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9zJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgbm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fcyA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfcyRsb2dsaWtzKSAKCnN5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fbm9fcyA8LSBzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zIDwtIHN5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8pICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCmBgYAoKIyMjIE5vIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBkCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9ndWVzc19zYW1lX3Nsb3BlX2QgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzRdICsgKDEgLSAyICogcFs0XSkgKiBwbm9ybSh4LCAtcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9kIDwtIHF1aWNrcHN5KGRhdF9zeW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZCwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSwgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9kJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZCRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgTm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgbm8gc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gZApgYGB7cn0Kc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZCA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfZCRsb2dsaWtzKSAKCnN5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fbm9fZCA8LSBzeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkgJT4lIAogIG11dGF0ZShiZXN0ID0gInNlbnNvcnkiKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QgPC0gc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZCAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiZGVjaXNpb24iKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSAKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3NfemVybyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbM10gKyAoMSAtIDIgKiBwWzNdKSAqIHBub3JtKHgsIDAsIHBbMV0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbM10gKyAoMSAtIDIgKiBwWzNdKSAqIHBub3JtKHgsIDAsIHBbMl0pKSkpCgpmaXRfc3ltX3NhbWVfZ3Vlc3NfemVybyA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX3plcm8sCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX3NjYWxlLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc196ZXJvJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3NfemVybyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgU2FtZSBndWVzcyBubyBzYW1lIHNsb3BlIHplcm8KYGBge3J9CnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfemVybyA8LSBtb2RlbF9zZWxlY3Rpb25fbHJ0KAogIGZpdF9zeW1fc2FtZV9ndWVzcyRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3NfemVybyRsb2dsaWtzKSAKCnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfemVybyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIG5vIHNhbWUgc2xvcGUgbm8gemVybyBzCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fcyA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0sIHBbMl0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0sIHBbM10pKSkpCgpmaXRfc3ltX3NhbWVfZ3Vlc3Nfbm9femVyb19zIDwtIHF1aWNrcHN5KGRhdF9zeW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX3NhbWVfZ3Vlc3Nfbm9femVyb19zLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fcyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgoKIyMjIFNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHZzIFNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHMKYGBge3J9CnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX3MkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fcyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIG5vIHNhbWUgc2xvcGUgbm8gemVybyBkCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fZCA8LSAgZGF0X3N5bSAlPiUgCiAgZGlzdGluY3QocmVmZXJlbmNlcykgJT4lIAogIGJpbmRfY29scyh0aWJibGUoZnVuID0gYygKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIHBbMV0sIHBbMl0pLCAKICAgIGZ1bmN0aW9uKHgsIHApIHBbNF0gKyAoMSAtIDIgKiBwWzRdKSAqIHBub3JtKHgsIC1wWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fZCA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX25vX3plcm9fZCwKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHZzIFNhbWUgZ3Vlc3Mgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3J9CnN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19kIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzJGxvZ2xpa3MsIAogIGZpdF9zeW1fc2FtZV9ndWVzc19ub196ZXJvX2QkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZCAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX2Z1bGwgPC0gc3ltX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAiZmlyc3QiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiZnVsbCIpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zIDwtIHN5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCmBgYAoKIyMjIFN5bSBzYW1lIGd1ZXNzIHNhbWUgc2xvcGUgemVybyAKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgcFsyXSArICgxIC0gMiAqIHBbMl0pICogcG5vcm0oeCwgMCwgcFsxXSksIAogICAgZnVuY3Rpb24oeCwgcCkgcFsyXSArICgxIC0gMiAqIHBbMl0pICogcG5vcm0oeCwgMCwgcFsxXSkpKSkKCmZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8sCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX3NjYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGluaV9sYXBzZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8kYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8kY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSB6ZXJvCmBgYHtyfQpzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYmVzdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8gPC0gc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvICU+JSAKICBzZW1pX2pvaW4oYmVzdF9zeW1fbm9fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkgCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfemVybyA8LSBzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX3plcm8gJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUpICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkgJT4lIAogIG11dGF0ZShiZXN0ID0gInplcm8iKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHMKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSkpKQoKZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19zIDwtIHF1aWNrcHN5KGRhdF9zeW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24sIHJlc3BvbnNlLCAKICAgICAgICAgICAgICAgIGdyb3VwaW5nID0gLihzdWJqZWN0LCB2ZXJ0aWNhbCwgcmVmZXJlbmNlcyksCiAgICAgICAgICAgICAgICBmdW4gPSBmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbmlfbGFwc2UpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgU2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgc2FtZSBndWVzcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MkbG9nbGlrcykgCgpzeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fcyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm8pICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYGBgCgojIyMgU3ltIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSBwWzNdICsgKDEgLSAyICogcFszXSkgKiBwbm9ybSh4LCAtcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZCA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaW5pX2xhcHNlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIFNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIHZzIHNhbWUgZ3Vlc3Mgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3J9CnN5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb192c19zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGUkbG9nbGlrcywgCiAgZml0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19kJGxvZ2xpa3MpIAoKc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2QgJT4lCiAgc2VtaV9qb2luKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2Z1bGwgPC0gc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJmdWxsIikKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X3N5bV9zYW1lX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAic2Vuc29yeSIpCgpgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIG5vIHNhbWUgc2xvcGUgemVybyAKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgMCwgcFsxXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgMCwgcFsyXSkpKSkKCmZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3plcm8gPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3plcm8sCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX3NjYWxlLCBwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfemVybyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfemVybyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlICAgdnMgYWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIHplcm8gCmBgYHtyfQpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzJGxvZ2xpa3MsIAogIGZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3plcm8kbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV96ZXJvICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX3MgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzNdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfcyA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfcywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfb3JpZ2luLCBwaW5pX3NjYWxlLCBwaW5pX3NjYWxlKSwKICAgICAgICAgICAgICAgIGJvb3RzdHJhcCA9ICJub25lIikKCmdncGxvdCgpICsgZmFjZXRfd3JhcChzdWJqZWN0IH4gdmVydGljYWwsIG5jb2wgPSA2KSArCiAgZ2VvbV9wb2ludChkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfcyRhdmVyYWdlcywgCiAgICAgICAgICAgICBhZXMoeCA9IG9yaWVudGF0aW9uLCB5ID0gcHJvYiwgY29sb3IgPSByZWZlcmVuY2VzKSkgKwogIGdlb21fbGluZShkYXRhID0gZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgYWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2Fic2VudF9sYXBzZXMkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfcyRsb2dsaWtzKSAKCnN5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19zICU+JQogIHNlbWlfam9pbihiZXN0X3N5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGUpICU+JSAKICBncm91cF9ieShiZXN0KSAlPiUgCiAgY291bnQoKQoKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBubyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAtcFsxXSwgcFszXSkpKSkKCmZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QgPC0gcXVpY2twc3koZGF0X3N5bSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvbiwgcmVzcG9uc2UsIAogICAgICAgICAgICAgICAgZ3JvdXBpbmcgPSAuKHN1YmplY3QsIHZlcnRpY2FsLCByZWZlcmVuY2VzKSwKICAgICAgICAgICAgICAgIGZ1biA9IGZ1bl9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QsCiAgICAgICAgICAgICAgICB4bWluID0gLTMsIHhtYXggPSAzLAogICAgICAgICAgICAgICAgcGFyaW5pID0gbGlzdChwaW5pX29yaWdpbiwgcGluaV9zY2FsZSwgcGluaV9zY2FsZSksCiAgICAgICAgICAgICAgICBib290c3RyYXAgPSAibm9uZSIpCgpnZ3Bsb3QoKSArIGZhY2V0X3dyYXAoc3ViamVjdCB+IHZlcnRpY2FsLCBuY29sID0gNikgKwogIGdlb21fcG9pbnQoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QkY3VydmVzLCAKICAgICAgICAgICAgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSByZWZlcmVuY2VzLCBsdHkgPSAiYWxsIikpICsKICB0aGVtZV9ncmV5KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIHZzIGFic2VudCBsYXBzZXMgbm8gc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3J9CnN5bV9hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX25vX3NhbWVfc2xvcGVfbm9femVyb19kIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzJGxvZ2xpa3MsIAogIGZpdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX2QkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZCAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCiMjIyBBZGQgdG8gcyB2cyBkCmJlc3RfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fcyA8LSBzeW1fYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZCAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSkgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJzZW5zb3J5IikKCmBgYAoKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgemVybwpgYGB7ciBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTV9CmZ1bl9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX3plcm8gPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAwLCBwWzFdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAwLCBwWzFdKSkpKQoKZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybyA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybywKICAgICAgICAgICAgICAgIHhtaW4gPSAtMywgeG1heCA9IDMsCiAgICAgICAgICAgICAgICBwYXJpbmkgPSBsaXN0KHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvJGF2ZXJhZ2VzLCAKICAgICAgICAgICAgIGFlcyh4ID0gb3JpZW50YXRpb24sIHkgPSBwcm9iLCBjb2xvciA9IHJlZmVyZW5jZXMpKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvJGN1cnZlcywgCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gcmVmZXJlbmNlcywgbHR5ID0gImFsbCIpKSArCiAgdGhlbWVfZ3JleSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpIApgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgbm8gemVybyB2cyBhYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgemVybwpgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvIDwtIG1vZGVsX3NlbGVjdGlvbl9scnQoCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUkbG9nbGlrcywgCiAgZml0X3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybyRsb2dsaWtzKSAKCnN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybyAlPiUKICBzZW1pX2pvaW4oYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlKSAlPiUgCiAgZ3JvdXBfYnkoYmVzdCkgJT4lIAogIGNvdW50KCkKCgpiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybyAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV96ZXJvIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybyAlPiUgCiAgc2VtaV9qb2luKGJlc3Rfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSkgJT4lIAogIGZpbHRlcihiZXN0ID09ICJzZWNvbmQiKSAlPiUgCiAgc2VsZWN0KHN1YmplY3QsIHZlcnRpY2FsKSAlPiUgCiAgbXV0YXRlKGJlc3QgPSAiemVybyIpCgpgYGAKCiMjIyBBYnNlbnQgbGFwc2VzIHNhbWUgc2xvcGUgbm8gemVybyBzCmBgYHtyIGZpZy5oZWlnaHQ9MTgsIGZpZy53aWR0aD0xNX0KZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zIDwtICBkYXRfc3ltICU+JSAKICBkaXN0aW5jdChyZWZlcmVuY2VzKSAlPiUgCiAgYmluZF9jb2xzKHRpYmJsZShmdW4gPSBjKAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSwgcFsyXSksIAogICAgZnVuY3Rpb24oeCwgcCkgMC4wMSArICgxIC0gMiAqIDAuMDEpICogcG5vcm0oeCwgcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fcyA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fcyRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gcwpgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fcyAlPiUKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgpiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX25vX3MgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gImZpcnN0IikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkKCgpiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3MgJT4lIAogIHNlbWlfam9pbihiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpIAoKCmBgYAoKIyMjIEFic2VudCBsYXBzZXMgc2FtZSBzbG9wZSBubyB6ZXJvIGQKYGBge3IgZmlnLmhlaWdodD0xOCwgZmlnLndpZHRoPTE1fQpmdW5fc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QgPC0gIGRhdF9zeW0gJT4lIAogIGRpc3RpbmN0KHJlZmVyZW5jZXMpICU+JSAKICBiaW5kX2NvbHModGliYmxlKGZ1biA9IGMoCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCBwWzFdLCBwWzJdKSwgCiAgICBmdW5jdGlvbih4LCBwKSAwLjAxICsgKDEgLSAyICogMC4wMSkgKiBwbm9ybSh4LCAtcFsxXSwgcFsyXSkpKSkKCmZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fZCA8LSBxdWlja3BzeShkYXRfc3ltLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uLCByZXNwb25zZSwgCiAgICAgICAgICAgICAgICBncm91cGluZyA9IC4oc3ViamVjdCwgdmVydGljYWwsIHJlZmVyZW5jZXMpLAogICAgICAgICAgICAgICAgZnVuID0gZnVuX3N5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19kLAogICAgICAgICAgICAgICAgeG1pbiA9IC0zLCB4bWF4ID0gMywKICAgICAgICAgICAgICAgIHBhcmluaSA9IGxpc3QocGluaV9vcmlnaW4sIHBpbmlfc2NhbGUpLAogICAgICAgICAgICAgICAgYm9vdHN0cmFwID0gIm5vbmUiKQoKZ2dwbG90KCkgKyBmYWNldF93cmFwKHN1YmplY3QgfiB2ZXJ0aWNhbCwgbmNvbCA9IDYpICsKICBnZW9tX3BvaW50KGRhdGEgPSBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QkYXZlcmFnZXMsIAogICAgICAgICAgICAgYWVzKHggPSBvcmllbnRhdGlvbiwgeSA9IHByb2IsIGNvbG9yID0gcmVmZXJlbmNlcykpICsKICBnZW9tX2xpbmUoZGF0YSA9IGZpdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fZCRjdXJ2ZXMsIAogICAgICAgICAgICBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IHJlZmVyZW5jZXMsIGx0eSA9ICJhbGwiKSkgKwogIHRoZW1lX2dyZXkoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAKYGBgCgojIyMgQWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gdnMgYWJzZW50IGxhcHNlcyBzYW1lIHNsb3BlIG5vIHplcm8gZApgYGB7cn0Kc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QgPC0gbW9kZWxfc2VsZWN0aW9uX2xydCgKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZSRsb2dsaWtzLCAKICBmaXRfc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QkbG9nbGlrcykgCgpzeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fZCAlPiUKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGdyb3VwX2J5KGJlc3QpICU+JSAKICBjb3VudCgpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QgPC0gc3ltX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX3ZzX2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QgJT4lIAogIHNlbWlfam9pbihiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvKSAlPiUgCiAgZmlsdGVyKGJlc3QgPT0gInNlY29uZCIpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJkZWNpc2lvbiIpCgojIyMgQWRkIHRvIHMgdnMgZApiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX25vX2RfcyA8LSBzeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fdnNfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm9fcyAlPiUgCiAgc2VtaV9qb2luKGJlc3RfYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlX25vX3plcm8pICU+JSAKICBmaWx0ZXIoYmVzdCA9PSAic2Vjb25kIikgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCkgJT4lIAogIG11dGF0ZShiZXN0ID0gInNlbnNvcnkiKQoKIyMjIEFkZCB0byBzIHZzIGQKYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19ub19zIDwtIHN5bV9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb192c19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19zICU+JSAKICBzZW1pX2pvaW4oYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVybykgJT4lIAogIGZpbHRlcihiZXN0ID09ICJmaXJzdCIpICU+JSAKICBmaWx0ZXIoIShzdWJqZWN0ID09IDkgJiB2ZXJ0aWNhbCA9PSBGQUxTRSkpICU+JSAKICBzZWxlY3Qoc3ViamVjdCwgdmVydGljYWwpICU+JSAKICBtdXRhdGUoYmVzdCA9ICJmdWxsIikKCmBgYAoKCiMjIyMgQWRkIGFsbCBiZXN0CmBgYHtyfQpiZXN0IDwtIGJlc3Rfc3ltX25vX3R3b19ndWVzc19zYW1lX3Nsb3BlX3plcm8gJT4lIAogIGJpbmRfcm93cyhiZXN0X3N5bV9ub190d29fZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX3MpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvKSAlPiUgCiAgYmluZF9yb3dzKGJlc3Rfc3ltX2d1ZXNzX3NhbWVfc2xvcGVfbm9femVyb19ub19kKSAlPiUgIAogIGJpbmRfcm93cyhiZXN0X3N5bV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fZCkgJT4lICAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fc2FtZV9ndWVzc19ub19zYW1lX3Nsb3BlX25vX3plcm9fZnVsbCkgJT4lIAogIGJpbmRfcm93cyhiZXN0X3N5bV9zYW1lX2d1ZXNzX25vX3NhbWVfc2xvcGVfbm9femVyb19zKSAlPiUgCiAgYmluZF9yb3dzKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV96ZXJvKSAlPiUgCiAgYmluZF9yb3dzKGJlc3Rfc3ltX3NhbWVfZ3Vlc3Nfc2FtZV9zbG9wZV9ub196ZXJvX2Z1bGwpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9zeW1fc2FtZV9ndWVzc19zYW1lX3Nsb3BlX25vX3plcm9fcykgJT4lIAogIGJpbmRfcm93cyhiZXN0X2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZV9ub196ZXJvX3MpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfemVybykgJT4lIAogIGJpbmRfcm93cyhiZXN0X2Fic2VudF9sYXBzZXNfc2FtZV9zbG9wZV9ub196ZXJvX2QpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19ub19kX3MpICU+JSAKICBiaW5kX3Jvd3MoYmVzdF9hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGVfbm9femVyb19ub19zKQoKCnJlZnMgPC0gZGF0X3N5bSAlPiUgZGlzdGluY3QodmVydGljYWwsIHJlZmVyZW5jZXMsIHJlZmVyZW5jZSkKCnN5bV9hdmVyYWdlc19zX3ZzX2RfYmVzdCA8LSAgc3ltX2F2ZXJhZ2VzX3NfdnNfZCAlPiUKICBsZWZ0X2pvaW4oYmVzdCkgJT4lIAogIGxlZnRfam9pbihyZWZzKQogIApzeW1fY3VydmVzX3NfdnNfZF9iZXN0IDwtIHN5bV9jdXJ2ZXNfc192c19kICU+JSAKICBsZWZ0X2pvaW4oYmVzdCkgJT4lIAogIGxlZnRfam9pbihyZWZzKQoKc3ltX3Bhcl9zX3ZzX2RfYmVzdCA8LSBzeW1fcGFyX3NfdnNfZCAlPiUgCiAgbGVmdF9qb2luKGJlc3QpIAoKc3ltX3Bhcl9zX3ZzX2RfYmVzdF9sb25nIDwtIHN5bV9wYXJfc192c19kX2Jlc3QgJT4lIAogIHNlbGVjdChzdWJqZWN0LCB2ZXJ0aWNhbCwgcGFyLCBiZXN0LCBwYXJuKSAlPiUgCiAgc3ByZWFkKHBhcm4sIHBhcikgCgpzeW1fcGFyX3NfdnNfZF9iZXN0X2FicyA8LSBzeW1fcGFyX3NfdnNfZF9iZXN0ICU+JSAKICAgICAgICAgICAgICBmaWx0ZXIocGFybiA9PSAicDEiIHwgcGFybiA9PSAicDIiKSAlPiUgCiAgICAgICAgICAgICAgbXV0YXRlKHBhcm4gPSBpZl9lbHNlKHBhcm4gPT0gInAxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbnNvcnlcbmJpYXMiLCAiRGVjaXNpb25hbFxuYmlhcyIpLAogICAgICAgICAgICAgICAgICAgICBhYnNfcGFyID0gYWJzKHBhcikpCgpgYGAKCiMjIyBTYXZlIGRhdGEKYGBge3J9CnNhdmUoYmVzdCwgZmlsZSA9ICJsb2dkYXRhL2Jlc3QuUkRhdGEiKQpzYXZlKHN5bV9hdmVyYWdlc19zX3ZzX2RfYmVzdCwgZmlsZSA9ICJsb2dkYXRhL3N5bV9hdmVyYWdlc19zX3ZzX2RfYmVzdC5SRGF0YSIpCnNhdmUoc3ltX2N1cnZlc19zX3ZzX2RfYmVzdCwgZmlsZSA9ICJsb2dkYXRhL3N5bV9jdXJ2ZXNfc192c19kX2Jlc3QuUkRhdGEiKQpzYXZlKHN5bV90aHJlX3NfdnNfZCwgZmlsZSA9ICJsb2dkYXRhL3N5bV90aHJlX3NfdnNfZC5SRGF0YSIpCnNhdmUoc3ltX3Bhcl9zX3ZzX2RfYmVzdCwgZmlsZSA9ICJsb2dkYXRhL3N5bV9wYXJfc192c19kX2Jlc3QuUkRhdGEiKQpzYXZlKHN5bV9wYXJfc192c19kX2Jlc3RfbG9uZywgZmlsZSA9ICJsb2dkYXRhL3N5bV9wYXJfc192c19kX2Jlc3RfbG9uZy5SRGF0YSIpCnNhdmUoc3ltX3Bhcl9zX3ZzX2RfYmVzdF9hYnMsIGZpbGUgPSAibG9nZGF0YS9zeW1fcGFyX3NfdnNfZF9iZXN0X2Ficy5SRGF0YSIpCnNhdmUoYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlLCBmaWxlID0gImxvZ2RhdGEvYmVzdF9zeW1fYWJzZW50X2xhcHNlc19zYW1lX3Nsb3BlLlJEYXRhIikKc2F2ZShiZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUsIGZpbGUgPSAibG9nZGF0YS9iZXN0X3N5bV9ub19hYnNlbnRfbGFwc2VzX3NhbWVfc2xvcGUuUkRhdGEiKQpzYXZlKGJlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZSwgZmlsZSA9ICJsb2dkYXRhL2Jlc3Rfc3ltX25vX2Fic2VudF9sYXBzZXNfbm9fc2FtZV9zbG9wZS5SRGF0YSIpCnNhdmUoYmVzdF9zeW1fbm9fc2FtZV9ndWVzcywgZmlsZSA9ICJsb2dkYXRhL2Jlc3Rfc3ltX25vX3NhbWVfZ3Vlc3MuUkRhdGEiKQoKYGBgCg==